package main

/*
什么是依赖
对象之间层层依赖
这样的话如果我想创建A->B->C->D, 如果我想创建一个A运行，那么我必须从底层往上层创建，而且还会导致必须先将底层的代码写好
创建A的时候，A必须要去创建B，B必须要去创建C，C必须要去创建D，这样的话，如果我想创建A，那么我必须先创建D，然后创建C，然后创建B，然后创建A
这个时候控制权在谁手上，在A

这种直接依赖会导致什么问题
1. 过度暴露细节
	A其实只需要B的方法，并不关心B的实现细节
2. 对象间的耦合度太高
	B发生了任何变化， 都可能会影响到A，如果这个时候A和B的开发者不是同一个人，那么这个时候就会导致A和B的开发者之间的沟通成本变高
	相对来说，如果这个依赖是通过接口来实现的，那么这个时候A和B的开发者之间的沟通成本就会变低
3. 依赖的创建过程太复杂
	工厂方法解决、ioc容器的话，就可以解决这个问题
4. 扩展性差

如果大家熟悉其他面向对象语言， java， python， 父类和子类， 依赖的是父类，其实这个问题可以得到解决的，
但是在go语言中，没有继承的概念，我们通过接口来解决这个问题， class比较重， 我们重点要知道的是面向对象解决了什么问题， 封装、继承、多态

但是没有解决创建过程的问题, 依赖的创建过程太复杂，工厂方法解决、ioc容器的话（spring），就可以解决这个问题
go中有没有这样一个库来解决ioc容器的问题， 如果你的项目越来越大，我们建议使用ioc容器，项目不大的情况下。建议使用工厂方法， 甚至不采用工厂方法，直接在main函数中创建对象，这样的话，代码的可读性会更高

创建过程的核心解决思想是控制反转 ioc(Inversion of Control ) - 工厂模式
DIP(Dependency Inversion Principle) 依赖倒置原则
依赖倒置原则是面向对象设计的基石，它指导我们如何降低对象之间的耦合度，提高系统的灵活性和可维护性
上层不应该依赖底层模块，他们之间应该通过抽象(父类、接口，接口)来互相依赖，
依赖反转， A->B A->(接口)->B
这样做的好处：
	1. 符合开闭原则
		接口通常比较稳定， 因此使得高层模块对修改封闭，对扩展开发
	2. 高内聚，低耦合
		代码不再收到控制依赖的限制，利于插件化、组件化

*/
